package controllers;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import models.Event;
import models.Offer;
import models.User;
import play.data.validation.*;

import play.data.validation.MaxSize;
import play.data.validation.MinSize;
import play.data.validation.Required;
import play.data.validation.Validation;
import play.db.jpa.Blob;
import play.libs.Codec;
import play.libs.MimeTypes;
import play.mvc.Controller;

public class Offers extends Controller {
	
	public enum UserAction{
		CREATE, EDIT, DELETE, VIEW
	}
	
	public static void edit(Long id) {
		List<Event> events = Search.searchForUpcomingEvents();
		User user = Security.getConnected();
		Offer offer = Offer.findById(id);
		notFoundIfNull(offer);
		flash.put("eventId", offer.event.id);
		UserAction userAction = UserAction.EDIT;
		render(user, events, offer, userAction);

	}
	
	public static void create(){
		List<Event> events = Search.searchForUpcomingEvents();
		User user = Security.getConnected();
		UserAction userAction = UserAction.CREATE;
		render(events, user, userAction);
	}
	
	/**
	 * 
	 * @param description
	 * @param startDate
	 * @param endDate
	 * @param streetNumber
	 * @param city
	 * @param street
	 * @param zipcode
	 * @param size
	 * @param price
	 * @param event
	 * @param user
	 * @throws FileNotFoundException 
	 */
	
	public static void save(Long offerId,
			
			@Required String description,

	@Required @MinSize(10) @MaxSize(10) String startDateString,

	@Required @MinSize(10) @MaxSize(10) String endDateString,

	@Required String city,

	@Required String street,
	
	@Required String streetNumber,

	@Required @MinSize(5) @MaxSize(5) int zipcode,

	@Required @MinSize(1) int size,

	@Required @MinSize(1) float price,

	@Required long eventId,
	
	@Required boolean premium,
	
	File picture) throws FileNotFoundException {
		
		int[] yearMonthDayStart = Tools.splitDate(startDateString);
		Date startDate = new GregorianCalendar(yearMonthDayStart[0], yearMonthDayStart[1]-1, yearMonthDayStart[2]).getTime();
		
		int[] yearMonthDayEnd = Tools.splitDate(endDateString);
		Date endDate = new GregorianCalendar(yearMonthDayEnd[0], yearMonthDayEnd[1]-1, yearMonthDayEnd[2]).getTime();
		
		// check start and endDate
		if (!Tools.isStartDateBeforeEndDate(startDate, endDate))
			validation.addError("startDate", "End Date is before Start Date");

		Event event = Event.findById(eventId);

		if (!Tools.isOfferWithinEventTimeRange(startDate, endDate, event))
			validation
					.addError(
							"startDate",
							"Your offer needs to be available during the event or at least for the day before.");

		// Handle errors
		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			create();
		}

		User user = Security.getConnected();

		if (user == null)
			Application.login();

		Offer offer;
		UserAction userAction;
		if (offerId == null){
			offer = new Offer(event, user);
			userAction = UserAction.CREATE;
		}
		else{
			offer = Offer.findById(offerId);
			userAction = UserAction.EDIT;
		}
		offer.city = city;
		offer.street = street;
		offer.streetNumber = streetNumber;
		offer.description = description;
		offer.endDate = endDate;
		offer.startDate = startDate;
		offer.price = price;
		offer.size = size;
		offer.zipcode = zipcode;
		offer.event = event;
		offer.user = user;
		offer.premium = premium;
		if (picture != null) {
    		offer.picture = new Blob();
    		offer.picture.set(new FileInputStream(picture), MimeTypes.getContentType(picture.getName()));
    	}
		event.save();
		offer.save();
		show(offer.id, userAction);

	}

	public static void delete(Long id){
		Offer offer = Offer.findById(id);
		if (offer !=null)
			offer.delete();
		UserAction userAction = UserAction.DELETE;
		show(null, userAction);
	}

	 public static void show(Long id, UserAction userAction) {
		 
		if (userAction == null)
			userAction = UserAction.VIEW;
		User user = Security.getConnected();
		
		if (id != null) {
			Offer offer = Offer.findById(id);
			notFoundIfNull(offer);
			User offerer = offer.user;
		    
		    offer.event.clicks++;
		    offer.event.save();
		        
		    render(offer, offerer, user, userAction);
		}
		render(user, userAction);
		
	    
	 }
	 
	 public static void showPicture(long id) {
		 Offer offer = Offer.findById(id);
			notFoundIfNull(offer);
			response.setContentTypeIfNotSet(offer.picture.type());
			java.io.InputStream picture = offer.picture.get();
			if (picture != null){
				renderBinary(picture);
			}
			else{
				renderBinary(new File("public/images/eventPicture.jpg"));
			}
		}
}

